package cn.edu.sgu.www.mhxysy.service.except.impl;

import cn.edu.sgu.www.mhxysy.pager.Pager;
import cn.edu.sgu.www.mhxysy.dto.except.AccountDTO;
import cn.edu.sgu.www.mhxysy.entity.except.Account;
import cn.edu.sgu.www.mhxysy.entity.role.RoleAccount;
import cn.edu.sgu.www.mhxysy.exception.GlobalException;
import cn.edu.sgu.www.mhxysy.mapper.except.AccountMapper;
import cn.edu.sgu.www.mhxysy.mapper.role.RoleAccountMapper;
import cn.edu.sgu.www.mhxysy.pager.except.AccountPager;
import cn.edu.sgu.www.mhxysy.redis.repository.impl.AccountRepository;
import cn.edu.sgu.www.mhxysy.restful.ResponseCode;
import cn.edu.sgu.www.mhxysy.service.except.AccountService;
import cn.edu.sgu.www.mhxysy.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author 沐雨橙风ιε
 * @version 1.0
 */
@Service
public class AccountServiceImpl implements AccountService {

    private final AccountMapper accountMapper;
    private final RoleAccountMapper roleAccountMapper;
    private final AccountRepository accountRepository;

    @Autowired
    public AccountServiceImpl(
            AccountMapper accountMapper,
            RoleAccountMapper roleAccountMapper,
            AccountRepository accountRepository) {
        this.accountMapper = accountMapper;
        this.roleAccountMapper = roleAccountMapper;
        this.accountRepository = accountRepository;
    }

    @Override
    public void insert(AccountDTO accountDTO) {
        // 验证账号是否重复
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();

        queryWrapper.eq("account", accountDTO.getAccount());

        long count = accountMapper.selectCount(queryWrapper);

        if (count > 0) {
            throw new GlobalException(ResponseCode.CONFLICT, "添加失败，账号已存在！");
        }

        Account account = new Account();

        account.setId(account.uuid());
        account.setPhone(accountDTO.getPhone());
        account.setAccount(accountDTO.getAccount());

        accountMapper.insert(account);

        // 删除缓存
        accountRepository.deleteList();
    }

    @Override
    public void deleteById(String accountId) {
        // 1、验证账号下是否有角色
        QueryWrapper<RoleAccount> queryWrapper = new QueryWrapper<>();

        queryWrapper.eq("account_id", accountId);

        // 通过账号ID查询角色数量
        long count = roleAccountMapper.selectCount(queryWrapper);

        // 角色数量大于0，禁止删除
        if (count > 0) {
            throw new GlobalException(ResponseCode.FORBIDDEN, "删除失败，请先删除该账号下的角色！");
        }

        // 2、删除账号
        accountMapper.deleteById(accountId);

        // 删除缓存
        accountRepository.deleteList();
        accountRepository.deleteById(accountId);
    }

    @Override
    public void updateById(AccountDTO accountDTO) {
        String accountId = accountDTO.getId();

        if (StringUtils.isEmpty(accountId)) {
            throw new GlobalException(ResponseCode.BAD_REQUEST, "账号ID不能为空！");
        }

        Account account = accountMapper.selectById(accountId);

        if (account == null) {
            throw new GlobalException(ResponseCode.NOT_FOUND, "修改失败，账号不存在！");
        }

        account.setAccount(accountDTO.getAccount());
        account.setPhone(accountDTO.getPhone());

        accountMapper.updateById(account);

        // 删除缓存
        accountRepository.deleteList();
        accountRepository.deleteById(accountId);
    }

    @Override
    public List<Account> selectAll() {
        return accountRepository.selectList();
    }

    @Override
    public Account selectById(String accountId) {
        return accountRepository.selectById(accountId);
    }

    @Override
    public Page<Account> selectByPage(AccountPager pager) {
        QueryWrapper<Account> queryWrapper = new QueryWrapper<>();
        Page<Account> page = Pager.ofPage(pager);

        queryWrapper.eq(
                StringUtils.isNotEmpty(pager.getPhone()),
                "phone", pager.getPhone()
        );

        return accountMapper.selectPage(page, queryWrapper);
    }

}